package org.funny.nn.som.old;

import java.util.*;

/**
 * 神经网络内核
 * @author: LinLW
 */
public class Neuron {
    /**
     * 产生size个随机位置的神经。这里的神经实际上就是随机的点。
     * @param  size 数量
     * @return double[][] 结果
     */
    public static List<Point> generateNetwork(int size){
        List<Point> ret=new ArrayList<>();
        for(int i=0;i<size;i++){
            ret.add(new Point(RANDOM.nextFloat(),RANDOM.nextFloat()));
        }
        return ret;
    }

            /*
            * Get the range gaussian of given radix around a center index.
            * @param: [center, raix, domain]
            * @return: double
            */
    public static double[] getNeighborhood(int center,double radix,int domain){
        // Impose an upper bound on the radix to prevent NaN and blocks
        if (radix < 1){
            radix = 1;
        }
        double[] ret=new double[domain];
        for(int i=0;i<domain;i++){
            int deltas=Math.abs(center-i);
            int distances=Math.min(deltas,domain-deltas);
            double gaussian =  Math.exp(-(distances*distances)* 1.0 / (2*radix*radix));
            ret[i]=gaussian;
        }
        return ret;
    }

    /**
     * 通过network的数据重新排序城市。
     * @param cities 城市
     * @param network 神经网络
     * @return List<City> 排序号的城市
     */
    public static List<City> getRoute(List<City> cities, List<Point> network){
        int[] ret=new int[cities.size()];
        int i=0;
        for(City city: cities){
            ret[i]=Distance.selectClosest(network,city);
            i++;
        }
        // 根据这个结果重新排序
        int[][] temp=new int[ret.length][2];
        for(int k=0;k<temp.length;k++){
            temp[k][0]=k;
            temp[k][1]=ret[k];
        }
        Arrays.sort(temp, Comparator.comparingInt(row -> row[1]));
        List<City> citiesReindex=new ArrayList<>();
        for(int[]t:temp){
            citiesReindex.add(cities.get(t[0]));
        }
        return citiesReindex;
    }

    private static Random RANDOM=new Random();
}
